home *** CD-ROM | disk | FTP | other *** search
- /*
- File: DumpARPCache.c
-
- Contains: Dumps the system ARP cache to stdout.
-
- Written by: Quinn "The Eskimo!"
-
- Copyright: © 1997 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- You may incorporate this sample code into your applications without
- restriction, though the sample code has been provided "AS IS" and the
- responsibility for its operation is 100% yours. However, what you are
- not permitted to do is to redistribute the source as "DSC Sample Code"
- after having made changes. If you're going to re-distribute the source,
- we require that you make it clear in the source that the code was
- descended from Apple Sample Code, but that you've made changes.
- */
-
- #include <stdio.h>
- #include <string.h>
-
- #include <OpenTptClient.h>
-
- // Pick up the symbolic name of the OT ARP module.
-
- #include <modnames.h>
-
- // #include <miioccom.h>
-
- // The following equates are actually exported by <miioccom.h>, but
- // they commented out for some reason )-:
-
- #define MIOC_ND 'c' /* ioctl's for Mentat's nd device */
-
- // The following equates define the two "Name Dispatch" ioctls
- // for setting and getting OT internal parameters.
-
- #define ND_GET MIOC_CMD(MIOC_ND, 0) /* Get a value */
- #define ND_SET MIOC_CMD(MIOC_ND, 1) /* Set a value */
-
- // The name of the Name Dispatch variable you have to get in
- // order to get a dump of the ARP cache.
-
- #define ARP_ND_CACHE_REPORT "arp_cache_report"
-
- /////////////////////////////////////////////////////////////////////
-
- // A global static buffer to store the ARP cache report. Obviously
- // a real application would have to allocate such a buffer dynamically.
-
- static char gDataBuffer[10000];
-
- static OSStatus DumpARPCache(void)
- // Dump the OT ARP cache to stdout.
- {
- OSStatus err;
- StreamRef arpStream;
- struct strioctl nddIOCommand;
- SInt32 i;
-
- // First open up a raw STREAMS connection to the ARP module.
-
- arpStream = OTStreamOpen(MI_ARP_NAME, 0, &err);
-
- if (err == noErr) {
-
- // Switch the stream in sync/blocking mode. To make the
- // code easier, we're going to do this synchronously.
-
- (void) OTStreamSetBlocking(arpStream);
- (void) OTStreamSetSynchronous(arpStream);
-
- // Copy the name of the ND variable we're trying
- // to get into our buffer.
-
- OTStrCopy(gDataBuffer, ARP_ND_CACHE_REPORT);
-
- // The ND_GET ioctl returns a value and sets ic_len. A negative
- // value is an error and you can give up now (-: The rule for
- // positive values is a bit weirder. ic_len is always set
- // to the amount of data that is actually returned. If the
- // data available exceeds the available buffer space (as
- // defined by the ic_len on input), the ioctl returns
- // a positive number that is the amount of buffer space
- // needed. So we first call it with a minimal buffer
- // then give it the buffer space it requires. Obviously
- // there's a concurrency race here, which we conveniently
- // ignore in this sample.
-
- // First get the size of data buffer we need to allocate.
-
- nddIOCommand.ic_cmd = ND_GET;
- nddIOCommand.ic_timout = 0;
- nddIOCommand.ic_len = strlen(ARP_ND_CACHE_REPORT) + 1; // Length of ND name including...
- nddIOCommand.ic_dp = gDataBuffer; // ...the zero terminator.
-
- err = OTStreamIoctl(arpStream, I_STR, &nddIOCommand);
- printf("First OTStreamIoctl reports err = %d\n", err);
- printf("First OTStreamIoctl reports ic_len = %d\n", nddIOCommand.ic_len);
-
- if (err >= noErr) {
-
- if (err > noErr) {
-
- // The first ioctl returned a positive number telling
- // us how big the data returned was. We turn around
- // around make the ioctl again, this time passing
- // in an appropriately sized buffer.
-
- OTStrCopy(gDataBuffer, ARP_ND_CACHE_REPORT);
-
- nddIOCommand.ic_cmd = ND_GET;
- nddIOCommand.ic_timout = 0;
- nddIOCommand.ic_len = err;
- nddIOCommand.ic_dp = gDataBuffer;
-
- err = OTStreamIoctl(arpStream, I_STR, &nddIOCommand);
- printf("Second OTStreamIoctl reports err = %d\n", err);
- printf("Second OTStreamIoctl reports ic_len = %d\n", nddIOCommand.ic_len);
- }
-
- if (err == noErr) {
-
- // Everything is cool, let's print out the data
- // returned to us from ARP. The format is straight
- // text with zero characters as the line terminator.
-
- err = noErr;
- for (i = 0; i < nddIOCommand.ic_len; i++) {
- if (gDataBuffer[i] == 0) {
- putchar('\n');
- } else {
- putchar(gDataBuffer[i]);
- }
- }
- } else {
- printf("Whoah, ARP table changed size!\n");
- }
- }
- }
-
- // Clean up.
-
- if (arpStream != nil) {
- (void) OTStreamClose(arpStream);
- }
- return (err);
- }
-
- /////////////////////////////////////////////////////////////////////
-
- void main(void)
- {
- OSStatus err;
-
- printf("Hello Cruel World!\n");
- printf("DumpARPCache -- Dumps the Open Transport ARP cache to stdout\n\n");
-
- err = InitOpenTransport();
-
- if (err == noErr) {
-
- err = DumpARPCache();
-
- CloseOpenTransport();
- }
-
- if (err == noErr) {
- printf("Success.\n");
- } else {
- printf("Failed with error %d.\n", err);
- }
- printf("Done. Press command-Q to Quit.\n");
- }
-